package Demo;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: DELL
 * Date: 2023-01-09
 * Time: 16:27
 */

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 线程池: 解决频繁创建销毁线程(虽然轻量,但频繁也会比较低效)
 *        将某个不在使用了的线程放入一个"池"中,下次如果在需要使用到该线程
 *        直接从池子中取,不必通过系统再来创建线程
 *
 * Executor Service 表示一个线程池实例
 * Executors 是一个工厂类, 能够创建出集中不同风格的线程池
 * Executor Service 的submit方法能够向线程池提交若干歌任务
 */

/**
 *  Executors 创建线程池的集中方式
 *  1. newFixedThreadPool: 创建固定线程数的线程池 --可控最大并发数线程池
 *  2. newCachedThreadPool: 创建线程数目动态增长的线程池 --可回收缓存线程池
 *  3. newSingleThreadExecutor: 创建只包含单个线程的线程池 --单线程化线程池(创建出来只有一个线程)
 *  4. newCachedThreadPool: 设定延迟时间后执行命令,或者定期执行命令.是进阶版本的Timer -- 可回收缓存线程池
 *
 *  Executors 本质上是ThreadPoolExecutor类的封装
 */

public class Thread_Demo16 {
    public static void main(String[] args) {
        // 提供一个线程池实例,初始线程池中有10个(自行指定)线程  是一个工厂方法(内部静态类)
        ExecutorService pool = Executors.newFixedThreadPool(10);

        // 向线程池中提交任务
        pool.submit(new Runnable() {
            // 使用一个Runnable 匿名内部类作为任务
            @Override
            public void run() {
                // working
                System.out.println("hello");//将由线程池中的十个线程来共同执行这个任务
            }
        });


        // 创建一个单线程化的实例
        ExecutorService pool1 = Executors.newSingleThreadExecutor();
        // 运用该单线程实现1+2+3...+...10;

            pool1.submit(new Runnable() {
                int sum = 0;
                @Override
                public void run() {
                    try {
                        for (int k = 1; k <= 10; k++) {
                            sum += k;
                            Thread.currentThread().setName("Thread i = " + k); // 发返回当前正在执行的线程对象并改名为 j
                            System.out.println(Thread.currentThread().getName() + " index = " + k);//
                            Thread.sleep(1000); // 保证先打印线程实例
                        }

                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    System.out.println(sum);

                }
            });

        //执行完以后启动有序关闭,其中先提交的任务先执行,但不会接受新任务
        pool1.shutdown();



         /** 作用: 用来创建一个可以无限增大的线程池。当有任务到来时，会判断当先线程池中是否有已经执行完被回收的空闲线程，
         * 有则使用，没有则创建新的线程。（空闲线程：线程如果60秒没有使用就会被认为是空闲线程并移出Cache）
         * 特点: 无限扩展、自动回收空闲线程、复用空闲线程
         * 使用场景：在小任务量，任务时间执行短的场景下提高性能
         * 注意：使用完要调用shutdown()来关闭执行器，如果不关闭，则一直等待新任务的到来
         * 异常可能(java.lang.OutOfMemoryError) : 任务量太大,线程池不断创建线程,超出了内存限制
         *
         * executor.execute(task); //把Runnable交给执行器执行*/


        ExecutorService pool2 = Executors.newCachedThreadPool();
        for (int i = 0; i < 100; i++) {
            pool2.execute(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName());
                }
            });
        }
    }
}
